Skip to content

Conversation

@Lu1zz
Copy link
Contributor

@Lu1zz Lu1zz commented Feb 20, 2025

Summary by CodeRabbit

  • New Features
    • Introduced comprehensive support for the TON blockchain, enabling TON address retrieval, message signing, and proof verification.
    • Integrated new CLI commands for TON operations, facilitating transaction and token management.
    • Added dedicated UI components and confirmation dialogs for TON transfers and related interactions.
    • Enhanced overall wallet functionality with TON-specific protocol handling and configuration improvements.
    • Added support for new message types and enumerations related to the TON ecosystem.

@Lu1zz Lu1zz requested a review from a team as a code owner February 20, 2025 07:44
@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2025

Walkthrough

This pull request integrates comprehensive support for the TON ecosystem. It includes updates to protobuf validations, new message types, and schema definitions. The changes introduce new modules for address generation, message signing, proof signing, and UI components. Additionally, it enhances the CLI with TON commands, updates wallet contract implementations, and adds utility functions and enumerations to facilitate structured communication and transaction processing within the TON framework.

Changes

File(s) Summary
common/protob/check.py, common/protob/messages.proto, common/protob/messages-ton.proto Updated file name validation to accept the "Ton" prefix; added new TON-specific protobuf definitions and message types.
core/SConscript.firmware, core/embed/firmware/memory_H.ld, core/embed/firmware/mpconfigport.h, core/embed/unix/mpconfigport.h Expanded build configuration for TON sources; included additional resources and MicroPython configuration updates.
core/src/all_modules.py, core/src/apps/ton/__init__.py, core/src/apps/ton/get_address.py, core/src/apps/ton/layout.py, core/src/apps/ton/sign_message.py, core/src/apps/ton/sign_proof.py, core/src/apps/ton/tokens.py Introduced new TON modules, constants, and functions for address generation, transaction layout, message signing, and token handling.
core/src/apps/ton/tonsdk/... Added TON SDK features, including cell and dictionary builders, contract classes (wallet, token, NFT), and related utility functions.
core/src/apps/workflow_handlers.py Extended the message handler mapping to include TON message types.
core/src/trezor/enums/... Added new TON message type enumerations, wallet version constants, and workchain definitions.
core/src/trezor/lvglui/scrs/template.py, core/src/trezor/messages.py, core/src/trezor/strings.py, core/src/trezor/ui/layouts/lvgl/... Added TON-specific UI screens, message classes, string formatting, and confirmation functions.
python/src/trezorlib/cli/ton.py, python/src/trezorlib/cli/trezorctl.py, python/src/trezorlib/messages.py, python/src/trezorlib/ton.py Integrated TON CLI commands and linked TON support into the Trezor CLI and messaging framework.

Sequence Diagram(s)

TON Get Address Flow

sequenceDiagram
    participant U as User
    participant G as get_address
    participant KC as Keychain
    participant W as Wallet
    participant D as Display

    U->>G: Request TON address with parameters
    G->>G: Validate path
    G->>KC: Derive node using address_n
    KC-->>G: Return derived key
    G->>G: Determine workchain and check wallet version
    G->>W: Create wallet instance with public key and params
    alt If show_display is true
      G->>D: Present generated address
    end
    G-->>U: Return TonAddress (public key & address)
Loading

TON Sign Message Flow

sequenceDiagram
    participant U as User
    participant S as sign_message
    participant KC as Keychain
    participant W as Wallet
    participant C as Confirmation/UI

    U->>S: Request to sign TON message
    S->>S: Validate path and message fields
    S->>KC: Derive key and wallet details
    KC-->>S: Return derived data
    S->>W: Create wallet instance and compute digest
    S->>C: Show confirmation screens
    C-->>S: User confirms transaction
    S->>S: Sign message using private key
    S-->>U: Return TonSignedMessage with signature
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or Summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Lu1zz Lu1zz requested a review from somebodyLi February 20, 2025 07:45
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.

🛑 Comments failed to post (113)
core/src/apps/ton/get_address.py (2)

19-22: 🧹 Nitpick (assertive)

Suggest adding a trailing comma in the function definition.
This improves readability and complies with lint rules.

 async def get_address(
-    ctx: Context, msg: TonGetAddress, keychain: Keychain
+    ctx: Context, msg: TonGetAddress, keychain: Keychain,
 ) -> TonAddress:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

@auto_keychain(__name__)
async def get_address(
    ctx: Context, msg: TonGetAddress, keychain: Keychain,
) -> TonAddress:
🧰 Tools
🪛 Ruff (0.8.2)

21-21: Trailing comma missing

Add trailing comma

(COM812)


36-39: 🧹 Nitpick (assertive)

Suggest adding a trailing comma in named parameters for better consistency.

 wallet = Wallets.ALL[wallet_version](
-    public_key=public_key, wallet_id=msg.wallet_id, wc=workchain
+    public_key=public_key, wallet_id=msg.wallet_id, wc=workchain,
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    wallet = Wallets.ALL[wallet_version](
        public_key=public_key, wallet_id=msg.wallet_id, wc=workchain,
    )
    address = wallet.address.to_string(
🧰 Tools
🪛 Ruff (0.8.2)

37-37: Trailing comma missing

Add trailing comma

(COM812)

core/src/apps/ton/tonsdk/contract/wallet/_wallet_contract_v3.py (3)

13-25: 🧹 Nitpick (assertive)

Add type hints to function parameters and return.
Explicit annotations make the code clearer.

-    def create_signing_message(self, expiration_time, seqno=None):
+    def create_signing_message(
+        self,
+        expiration_time: int,
+        seqno: int | None = None,
+    ) -> Cell:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def create_signing_message(
        self,
        expiration_time: int,
        seqno: int | None = None,
    ) -> Cell:
        seqno = seqno or 0
        message = Cell()
        message.bits.write_uint(self.options["wallet_id"], 32)
        if seqno == 0:
            for _ in range(32):
                message.bits.write_bit(1)
        else:
            message.bits.write_uint(expiration_time, 32)

        message.bits.write_uint(seqno, 32)
        return message
🧰 Tools
🪛 Ruff (0.8.2)

13-13: Missing return type annotation for private function create_signing_message

(ANN202)


13-13: Missing type annotation for function argument expiration_time

(ANN001)


13-13: Missing type annotation for function argument seqno

(ANN001)


5-11: 🧹 Nitpick (assertive)

Add return type annotation to create_data_cell.
It helps future readers know what to expect.

 def create_data_cell(self):
+    """Create and return a new Cell."""
     cell = Cell()

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

6-6: Missing return type annotation for private function create_data_cell

(ANN202)


28-35: 🧹 Nitpick (assertive)

Add type annotations for __init__ and **kwargs.
This clarifies what options can be passed.

-    def __init__(self, **kwargs) -> None:
+    def __init__(self, **kwargs: int | str) -> None:

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

28-28: Missing type annotation for **kwargs

(ANN003)

core/src/apps/ton/sign_proof.py (2)

20-23: 🧹 Nitpick (assertive)

Suggest adding a trailing comma in function signature.
This ensures consistency with lint rules.

 async def sign_proof(
-    ctx: Context, msg: TonSignProof, keychain: Keychain
+    ctx: Context, msg: TonSignProof, keychain: Keychain,
 ) -> TonSignedProof:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

@auto_keychain(__name__)
async def sign_proof(
    ctx: Context, msg: TonSignProof, keychain: Keychain,
) -> TonSignedProof:
🧰 Tools
🪛 Ruff (0.8.2)

22-22: Trailing comma missing

Add trailing comma

(COM812)


37-39: 🧹 Nitpick (assertive)

Add a trailing comma to match style guidelines.

 wallet = Wallets.ALL[wallet_version](
-    public_key=public_key, wallet_id=msg.wallet_id, wc=workchain
+    public_key=public_key, wallet_id=msg.wallet_id, wc=workchain,
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    wallet = Wallets.ALL[wallet_version](
        public_key=public_key, wallet_id=msg.wallet_id, wc=workchain,
    )
🧰 Tools
🪛 Ruff (0.8.2)

38-38: Trailing comma missing

Add trailing comma

(COM812)

core/src/apps/ton/tonsdk/contract/token/ft/jetton_minter.py (1)

10-13: 🧹 Nitpick (assertive)

Add type annotations for clarity.
You can annotate __init__ to return None and specify types for **kwargs. This clarifies intent and aids tooling.

🧰 Tools
🪛 Ruff (0.8.2)

10-10: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


10-10: Missing type annotation for **kwargs

(ANN003)

python/src/trezorlib/ton.py (3)

11-31: 🧹 Nitpick (assertive)

Add return annotations and handle booleans.
Static analysis suggests adding a return type for get_address. You might also make the boolean parameters keyword-only to reduce confusion.

🧰 Tools
🪛 Ruff (0.8.2)

12-12: Missing return type annotation for public function get_address

(ANN201)


16-16: Boolean-typed positional argument in function definition

(FBT001)


16-16: Boolean default positional argument in function definition

(FBT002)


17-17: Boolean-typed positional argument in function definition

(FBT001)


17-17: Boolean default positional argument in function definition

(FBT002)


19-19: Boolean-typed positional argument in function definition

(FBT001)


19-19: Boolean default positional argument in function definition

(FBT002)


28-28: Trailing comma missing

Add trailing comma

(COM812)


29-29: Trailing comma missing

Add trailing comma

(COM812)


33-88: 🧹 Nitpick (assertive)

Refine optional parameter typing.
jetton_amount_bytes, ext_destination, ext_ton_amount, or ext_payload can be None. Convert them to Optional[...] to follow PEP 484.

🧰 Tools
🪛 Ruff (0.8.2)

33-33: Missing return type annotation for public function sign_message

(ANN201)


46-46: Boolean-typed positional argument in function definition

(FBT001)


46-46: Boolean default positional argument in function definition

(FBT002)


50-50: Boolean-typed positional argument in function definition

(FBT001)


50-50: Boolean default positional argument in function definition

(FBT002)


51-51: Boolean-typed positional argument in function definition

(FBT001)


51-51: Boolean default positional argument in function definition

(FBT002)


52-52: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)


53-53: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)


54-54: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)


55-55: PEP 484 prohibits implicit Optional

Convert to Optional[T]

(RUF013)


55-55: Trailing comma missing

Add trailing comma

(COM812)


86-86: Trailing comma missing

Add trailing comma

(COM812)


87-87: Trailing comma missing

Add trailing comma

(COM812)


90-116: 🧹 Nitpick (assertive)

Add a return type for clarity.
Add a return annotation for sign_proof. Also consider making the boolean args keyword-only if you want explicit calls.

🧰 Tools
🪛 Ruff (0.8.2)

91-91: Missing return type annotation for public function sign_proof

(ANN201)


99-99: Boolean-typed positional argument in function definition

(FBT001)


99-99: Boolean default positional argument in function definition

(FBT002)


100-100: Boolean-typed positional argument in function definition

(FBT001)


100-100: Boolean default positional argument in function definition

(FBT002)


115-115: Trailing comma missing

Add trailing comma

(COM812)

core/src/apps/ton/tonsdk/contract/wallet/_wallet_contract.py (3)

25-29: 🧹 Nitpick (assertive)

Use a custom exception for clarity.
Exception("WalletContract required publicKey...") can be replaced with a domain-specific exception. It helps debugging.

🧰 Tools
🪛 Ruff (0.8.2)

25-25: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


25-25: Missing type annotation for **kwargs

(ANN003)


27-27: Create your own exception

(TRY002)


27-27: Avoid specifying long messages outside the exception class

(TRY003)


30-35: 🧹 Nitpick (assertive)

Return type annotation helps.
Add a return annotation to create_data_cell (e.g., -> Cell). Boosts readability and tools support.

🧰 Tools
🪛 Ruff (0.8.2)

30-30: Missing return type annotation for private function create_data_cell

(ANN202)


36-41: 🧹 Nitpick (assertive)

Add type hints for _expiration_time and seqno.
Clarifies usage and ensures consistent usage across your codebase.

🧰 Tools
🪛 Ruff (0.8.2)

36-36: Missing return type annotation for private function create_signing_message

(ANN202)


36-36: Missing type annotation for function argument _expiration_time

(ANN001)


36-36: Missing type annotation for function argument seqno

(ANN001)

core/src/apps/ton/tonsdk/boc/dict/serialize_dict.py (5)

178-182: 🧹 Nitpick (assertive)

General type hints would improve readability.
Consider annotating function arguments and return types across this file to help future maintainers.

🧰 Tools
🪛 Ruff (0.8.2)

178-178: Missing return type annotation for public function serialize_dict

(ANN201)


178-178: Missing type annotation for function argument src

(ANN001)


178-178: Missing type annotation for function argument key_size

(ANN001)


178-178: Missing type annotation for function argument serializer

(ANN001)


43-43: 🧹 Nitpick (assertive)

Retrieve first dict value with a clearer approach.
Using next(iter(...)) is more explicit than [0], and it avoids slicing overhead.

-43 return {"type": "leaf", "value": list(src.values())[0]}
+43 return {"type": "leaf", "value": next(iter(src.values()))}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        return {"type": "leaf", "value": next(iter(src.values()))}
🧰 Tools
🪛 Ruff (0.8.2)

43-43: Prefer next(iter(src.values())) over single element slice

Replace with next(iter(src.values()))

(RUF015)


125-129: 🧹 Nitpick (assertive)

Use a direct check for repeated characters.
Code is simpler with a single expression.

-125 for e in src[1:]:
-126     if e != src[0]:
-127         return False
-128
-129 return True
+125 return all(e == src[0] for e in src[1:])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    return all(e == src[0] for e in src[1:])
🧰 Tools
🪛 Ruff (0.8.2)

125-129: Use return all(e == src[0] for e in src[1:]) instead of for loop

Replace with return all(e == src[0] for e in src[1:])

(SIM110)


17-17: 🧹 Nitpick (assertive)

Remove the unnecessary else.
Short-circuiting at line 15 returns immediately if length is zero. Remove the else to simplify.

15     if length == 0:
16         return src
-17     else:
+17     # direct block without else:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    if length == 0:
        return src
    # direct block without else:
🧰 Tools
🪛 Ruff (0.8.2)

17-17: Unnecessary else after return statement

Remove unnecessary else

(RET505)


26-36: 🛠️ Refactor suggestion

Avoid relying on assert in production code.
Use standard exception handling so code doesn't skip checks when Python is run without assertions. Also note line 36 has a misleading message referencing "Left" instead of "Right."

-26 assert len(src) > 0, "Internal inconsistency"
+26 if not src:
+27     raise ValueError("Internal inconsistency: empty source")
 ...
-35 assert len(left) > 0, "Internal inconsistency. Left empty."
-36 assert len(right) > 0, "Internal inconsistency. Left empty."
+35 if not left:
+36     raise ValueError("Internal inconsistency: left is empty.")
+37 if not right:
+38     raise ValueError("Internal inconsistency: right is empty.")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    if not src:
        raise ValueError("Internal inconsistency: empty source")
    left = {}
    right = {}
    for k in src:
        if k.find("0") == 0:
            left[k[1:]] = src[k]
        else:
            right[k[1:]] = src[k]

    if not left:
        raise ValueError("Internal inconsistency: left is empty.")
    if not right:
        raise ValueError("Internal inconsistency: right is empty.")
🧰 Tools
🪛 Ruff (0.8.2)

26-26: Use of assert detected

(S101)


35-35: Use of assert detected

(S101)


36-36: Use of assert detected

(S101)

core/src/apps/ton/tonsdk/utils/_address.py (2)

8-8: 🧹 Nitpick (assertive)

Use domain-specific exceptions instead of Exception.
Custom exceptions or ValueError/wire.DataError can clarify error causes and keep messages short.

-8 raise Exception("User-friendly address should contain strictly 48 characters")
+8 raise ValueError("Address must be 48 characters long")

(Apply similarly for other exception lines.)

Also applies to: 14-14, 20-20, 29-29, 38-38, 56-56, 81-81, 85-85, 89-89

🧰 Tools
🪛 Ruff (0.8.2)

8-8: Create your own exception

(TRY002)


8-8: Avoid specifying long messages outside the exception class

(TRY003)


33-36: 🧹 Nitpick (assertive)

Simplify assignment with a ternary expression.
This reduces code length and reads more directly.

-33 if addr[1] == 0xFF:
-34     workchain = -1
-35 else:
-36     workchain = addr[1]
+33 workchain = -1 if addr[1] == 0xFF else addr[1]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    workchain = -1 if addr[1] == 0xFF else addr[1]
🧰 Tools
🪛 Ruff (0.8.2)

33-36: Use ternary operator workchain = -1 if addr[1] == 255 else addr[1] instead of if-else-block

Replace if-else-block with workchain = -1 if addr[1] == 255 else addr[1]

(SIM108)

core/src/apps/ton/sign_message.py (5)

24-26: 🛠️ Refactor suggestion

High cyclomatic complexity.
Break sign_message into smaller helper functions to improve readability and maintainability.

🧰 Tools
🪛 Ruff (0.8.2)

24-24: sign_message is too complex (11 > 10)

(C901)


25-25: Trailing comma missing

Add trailing comma

(COM812)


25-25: 🧹 Nitpick (assertive)

Add trailing commas for readability.
Trailing commas in parameter lists and calls can make diffs cleaner.

Also applies to: 43-43, 93-93

🧰 Tools
🪛 Ruff (0.8.2)

25-25: Trailing comma missing

Add trailing comma

(COM812)


57-57: 🧹 Nitpick (assertive)

Explicitly name boolean parameters.
Using positional True/False is confusing. Consider naming keyword args to clarify meaning.

🧰 Tools
🪛 Ruff (0.8.2)

57-57: Boolean positional value in function call

(FBT003)


57-57: Boolean positional value in function call

(FBT003)


150-150: 🧹 Nitpick (assertive)

Combine with the previous return.
The elif is unnecessary since the prior branch returned. This keeps it simple.

-150 elif msg.jetton_amount_bytes is not None and msg.jetton_master_address is not None:
+150 if msg.jetton_amount_bytes is not None and msg.jetton_master_address is not None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    if msg.jetton_amount_bytes is not None and msg.jetton_master_address is not None:
🧰 Tools
🪛 Ruff (0.8.2)

150-150: Unnecessary elif after return statement

Remove unnecessary elif

(RET505)


11-11: 🧹 Nitpick (assertive)

Remove the unused import.
Cell appears unused here. Clean up to reduce clutter.

-11 from apps.ton.tonsdk.boc import Cell
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.


🧰 Tools
🪛 Ruff (0.8.2)

11-11: apps.ton.tonsdk.boc.Cell imported but unused

Remove unused import: apps.ton.tonsdk.boc.Cell

(F401)

core/src/apps/ton/tonsdk/contract/token/nft/nft_collection.py (8)

13-13: 🧹 Nitpick (assertive)

Add type hints for clarity.
Add a return type hint as -> None and annotate **kwargs if feasible.

🧰 Tools
🪛 Ruff (0.8.2)

13-13: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


13-13: Missing type annotation for **kwargs

(ANN003)


22-22: 🧹 Nitpick (assertive)

Annotate the parameter.
Give params a type hint (e.g. dict).

🧰 Tools
🪛 Ruff (0.8.2)

22-22: Missing type annotation for function argument params

(ANN001)


35-35: 🧹 Nitpick (assertive)

Add type hints for params.
Clearly specify the expected dictionary keys or a dedicated dataclass for params.

🧰 Tools
🪛 Ruff (0.8.2)

35-35: Missing type annotation for function argument params

(ANN001)


72-75: 🛠️ Refactor suggestion

Use modern generics.
Replace List[Tuple[str, Address]] with list[tuple[str, Address]].

🧰 Tools
🪛 Ruff (0.8.2)

75-75: Use list instead of List for type annotation

Replace with list

(UP006)


75-75: Use tuple instead of Tuple for type annotation

Replace with tuple

(UP006)


103-103: 🧹 Nitpick (assertive)

Add a trailing comma.
Keeps formatting consistent and helps future diffs.

🧰 Tools
🪛 Ruff (0.8.2)

103-103: Trailing comma missing

Add trailing comma

(COM812)


19-19: 🧹 Nitpick (assertive)

Add a trailing comma for style consistency.
This improves readability.

-            self.options.get("royalty", 0) * self.options["royalty_base"]
+            self.options.get("royalty", 0) * self.options["royalty_base"],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            self.options.get("royalty", 0) * self.options["royalty_base"],
🧰 Tools
🪛 Ruff (0.8.2)

19-19: Trailing comma missing

Add trailing comma

(COM812)


111-113: 🧹 Nitpick (assertive)

Throw a custom exception.
Define a specialized exception instead of using a bare Exception.

-            raise Exception("royalty must be less than 1")
+            class RoyaltyValueError(ValueError):
+                pass
+            raise RoyaltyValueError("royalty must be less than 1")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def create_edit_content_body(self, params) -> Cell:
        if params["royalty"] > 1:
            class RoyaltyValueError(ValueError):
                pass
            raise RoyaltyValueError("royalty must be less than 1")
🧰 Tools
🪛 Ruff (0.8.2)

111-111: Missing type annotation for function argument params

(ANN001)


113-113: Create your own exception

(TRY002)


113-113: Avoid specifying long messages outside the exception class

(TRY003)


2-2: 🧹 Nitpick (assertive)

Use modern type hints.
Replace List and Tuple with built-in generic types: list and tuple.

- from typing import List, Tuple
+ from typing import List as _List, Tuple as _Tuple
+ # (Optionally) direct usage: from typing import List, Tuple
# But for Python 3.9+, you can do:
- def create_batch_mint_body(self, contents_and_owners: List[Tuple[str, Address]], ...):
+ def create_batch_mint_body(self, contents_and_owners: list[tuple[str, Address]], ...):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

from typing import List as _List, Tuple as _Tuple
# (Optionally) direct usage: from typing import List, Tuple

def create_batch_mint_body(self, contents_and_owners: list[tuple[str, Address]], ...):
    # function body remains unchanged
    ...
🧰 Tools
🪛 Ruff (0.8.2)

2-2: typing.List is deprecated, use list instead

(UP035)


2-2: typing.Tuple is deprecated, use tuple instead

(UP035)

core/src/apps/ton/tonsdk/contract/__init__.py (6)

8-8: 🧹 Nitpick (assertive)

Add type hints.
Include -> None for the __init__ and annotate **kwargs.

🧰 Tools
🪛 Ruff (0.8.2)

8-8: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


8-8: Missing type annotation for **kwargs

(ANN003)


21-21: 🧹 Nitpick (assertive)

Return type hint missing.
Add -> dict for clarity.

🧰 Tools
🪛 Ruff (0.8.2)

21-21: Missing return type annotation for public function create_state_init

(ANN201)


63-63: 🧹 Nitpick (assertive)

Add param and return type hints.
They help readers and tools.

🧰 Tools
🪛 Ruff (0.8.2)

63-63: Missing return type annotation for classmethod create_external_message_header

(ANN206)


63-63: Missing type annotation for function argument dest

(ANN001)


63-63: Missing type annotation for function argument src

(ANN001)


63-63: Missing type annotation for function argument import_fee

(ANN001)


72-85: 🧹 Nitpick (assertive)

Refine boolean parameters.
Instead of many boolean parameters, consider an options object or named constants for clarity.

🧰 Tools
🪛 Ruff (0.8.2)

72-72: Missing return type annotation for classmethod create_internal_message_header

(ANN206)


74-74: Missing type annotation for function argument dest

(ANN001)


75-75: Missing type annotation for function argument grams

(ANN001)


76-76: Boolean default positional argument in function definition

(FBT002)


76-76: Missing type annotation for function argument ihr_disabled

(ANN001)


77-77: Missing type annotation for function argument bounce

(ANN001)


78-78: Boolean default positional argument in function definition

(FBT002)


78-78: Missing type annotation for function argument bounced

(ANN001)


79-79: Missing type annotation for function argument src

(ANN001)


80-80: Missing type annotation for function argument currency_collection

(ANN001)


81-81: Missing type annotation for function argument ihr_fees

(ANN001)


82-82: Missing type annotation for function argument fwd_fees

(ANN001)


83-83: Missing type annotation for function argument created_lt

(ANN001)


84-84: Missing type annotation for function argument created_at

(ANN001)


99-99: 🧹 Nitpick (assertive)

Use specialized exception.
Don't rely on bare Exception("...not implemented").

🧰 Tools
🪛 Ruff (0.8.2)

99-99: Create your own exception

(TRY002)


99-99: Avoid specifying long messages outside the exception class

(TRY003)


40-40: 🧹 Nitpick (assertive)

Use a custom exception.
Replace raise Exception(...) with a specialized exception to clarify error handling.

-            raise Exception("Contract: options.code is not defined")
+            class CodeNotDefinedError(ValueError):
+                pass
+            raise CodeNotDefinedError("Contract: options.code is not defined")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            class CodeNotDefinedError(ValueError):
                pass
            raise CodeNotDefinedError("Contract: options.code is not defined")
🧰 Tools
🪛 Ruff (0.8.2)

40-40: Create your own exception

(TRY002)


40-40: Avoid specifying long messages outside the exception class

(TRY003)

core/src/apps/ton/tonsdk/boc/_cell.py (8)

22-22: 🧹 Nitpick (assertive)

Add return type annotation for init.
Helps with clarity.

🧰 Tools
🪛 Ruff (0.8.2)

22-22: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


27-28: 🧹 Nitpick (assertive)

Add type hints.
Use -> str for __repr__.

🧰 Tools
🪛 Ruff (0.8.2)

27-27: Missing return type annotation for special method __repr__

Add return type annotation: str

(ANN204)


28-28: Use explicit conversion flag

Replace with conversion flag

(RUF010)


33-33: 🧹 Nitpick (assertive)

Return type annotation missing.
Add -> bytes for bytes_hash.

🧰 Tools
🪛 Ruff (0.8.2)

33-33: Missing return type annotation for private function bytes_hash

(ANN202)


74-74: 🧹 Nitpick (assertive)

Add trailing comma.
Increase consistency.

🧰 Tools
🪛 Ruff (0.8.2)

74-74: Trailing comma missing

Add trailing comma

(COM812)


184-184: 🧹 Nitpick (assertive)

Use custom exception for clarity.
Replace Exception("Expected 1 root cell") with a domain-specific error.

🧰 Tools
🪛 Ruff (0.8.2)

184-184: Create your own exception

(TRY002)


184-184: Avoid specifying long messages outside the exception class

(TRY003)


221-221: 🧹 Nitpick (assertive)

Reduce complexity.
parse_boc_header is quite large. Break it into smaller helper functions if possible.

🧰 Tools
🪛 Ruff (0.8.2)

221-221: parse_boc_header is too complex (16 > 10)

(C901)


221-221: Missing return type annotation for private function parse_boc_header

(ANN202)


221-221: Missing type annotation for function argument serialized_boc

(ANN001)


338-338: 🧹 Nitpick (assertive)

Use a custom exception.
Make error messages more contextual.

🧰 Tools
🪛 Ruff (0.8.2)

338-338: Create your own exception

(TRY002)


338-338: Avoid specifying long messages outside the exception class

(TRY003)


45-45: 🧹 Nitpick (assertive)

Eliminate the temporary bytes call.
Use a literal like x = b"" instead.

- x = bytes()
+ x = b""
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        x = b""
🧰 Tools
🪛 Ruff (0.8.2)

45-45: Unnecessary bytes call (rewrite as a literal)

Replace with bytes literal

(UP018)

core/src/apps/ton/__init__.py (2)

8-8: ⚠️ Potential issue

Use relative paths for resources

Hardcoded absolute paths can break across different environments. Use relative paths instead.

-ICON = "A:/res/chain-ton.png"
+ICON = "res/chain-ton.png"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

ICON = "res/chain-ton.png"

1-8: 🧹 Nitpick (assertive)

Add docstrings to explain constants

Add docstrings to explain the purpose and usage of each constant. This helps other developers understand the code better.

+"""Cryptographic curve used for TON operations."""
 CURVE = "ed25519"

+"""SLIP-0010 coin type identifier for TON."""
 SLIP44_ID = 607
 # https://github.com/satoshilabs/slips/blob/master/slip-0010.md

+"""Derivation path pattern for TON wallets."""
 PATTERN = "m/44'/coin_type'/account'"
+"""Primary color used in TON UI elements."""
 PRIMARY_COLOR = 0x0098EA
+"""Path to TON chain icon."""
 ICON = "res/chain-ton.png"

Committable suggestion skipped: line range outside the PR's diff.

core/src/apps/ton/tonsdk/boc/__init__.py (1)

5-13: 🧹 Nitpick (assertive)

Sort all list for better maintainability

Sort the all list alphabetically to make it easier to maintain.

 __all__ = [
-    "Cell",
-    "Builder",
-    "begin_cell",
-    "DictBuilder",
-    "begin_dict",
-    "deserialize_cell_data",
-    "parse_boc_header",
+    "begin_cell",
+    "begin_dict",
+    "Builder",
+    "Cell",
+    "deserialize_cell_data",
+    "DictBuilder",
+    "parse_boc_header",
 ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

__all__ = [
    "begin_cell",
    "begin_dict",
    "Builder",
    "Cell",
    "deserialize_cell_data",
    "DictBuilder",
    "parse_boc_header",
]
🧰 Tools
🪛 Ruff (0.8.2)

5-13: __all__ is not sorted

Apply an isort-style sorting to __all__

(RUF022)

core/src/apps/ton/tonsdk/boc/dict/find_common_prefix.py (3)

3-6: 🛠️ Refactor suggestion

Add input validation for src parameter

Validate that src contains only strings to prevent runtime errors.

+    if not all(isinstance(s, str) for s in src):
+        raise TypeError("All elements in src must be strings")
     if len(src) == 0:
         return ""
     if len(src) == 1:
         return src[0]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    if not all(isinstance(s, str) for s in src):
        raise TypeError("All elements in src must be strings")
    if len(src) == 0:
        return ""
    if len(src) == 1:
        return src[0]

1-1: 🧹 Nitpick (assertive)

Add type annotations for better code clarity

Add type hints to improve code readability and enable better type checking.

-def find_common_prefix(src):
+from typing import List
+
+def find_common_prefix(src: List[str]) -> str:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

from typing import List

def find_common_prefix(src: List[str]) -> str:
🧰 Tools
🪛 Ruff (0.8.2)

1-1: The file is executable but no shebang is present

(EXE002)


1-1: Missing return type annotation for public function find_common_prefix

(ANN201)


1-1: Missing type annotation for function argument src

(ANN001)


11-15: ⚠️ Potential issue

Fix potential IndexError in string comparison

The current implementation might raise IndexError when comparing strings of different lengths.

-    for i, e in enumerate(_sorted[0]):
-        if e == _sorted[-1][i]:
+    min_length = min(len(_sorted[0]), len(_sorted[-1]))
+    for i in range(min_length):
+        if _sorted[0][i] != _sorted[-1][i]:
             size += 1
         else:
             break

Committable suggestion skipped: line range outside the PR's diff.

core/src/apps/ton/tonsdk/utils/__init__.py (1)

13-23: 🧹 Nitpick (assertive)

Sort the __all__ list alphabetically.

Sort the list to improve readability and maintainability.

 __all__ = [
     "Address",
-    "concat_bytes",
-    "move_to_end",
-    "tree_walk",
-    "crc32c",
-    "crc16",
-    "read_n_bytes_uint_from_array",
-    "compare_bytes",
-    "int_to_hex",
+    "compare_bytes",
+    "concat_bytes",
+    "crc16",
+    "crc32c",
+    "int_to_hex",
+    "move_to_end",
+    "read_n_bytes_uint_from_array",
+    "tree_walk",
 ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

__all__ = [
    "Address",
    "compare_bytes",
    "concat_bytes",
    "crc16",
    "crc32c",
    "int_to_hex",
    "move_to_end",
    "read_n_bytes_uint_from_array",
    "tree_walk",
]
🧰 Tools
🪛 Ruff (0.8.2)

13-23: __all__ is not sorted

Apply an isort-style sorting to __all__

(RUF022)

core/src/apps/ton/tokens.py (2)

12-17: 🧹 Nitpick (assertive)

Move hardcoded addresses to constants.

Define token addresses as constants at module level to improve maintainability.

+JUSDT_TOKEN_ADDRESS = "EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA"
+USDT_TOKEN_ADDRESS = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"
+NOT_TOKEN_ADDRESS = "EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT"

 def token_by_address(token_type: str, address: str) -> TokenInfo:
     if token_type == "TON_TOKEN":
-        if address == "EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA":
+        if address == JUSDT_TOKEN_ADDRESS:
             return TokenInfo("jUSDT", 6)
-        if address == "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs":
+        if address == USDT_TOKEN_ADDRESS:
             return TokenInfo("USDT", 6)
-        if address == "EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT":
+        if address == NOT_TOKEN_ADDRESS:
             return TokenInfo("NOT", 9)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

JUSDT_TOKEN_ADDRESS = "EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA"
USDT_TOKEN_ADDRESS = "EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs"
NOT_TOKEN_ADDRESS = "EQAvlWFDxGF2lXm67y4yzC17wYKD9A0guwPkMs1gOsM__NOT"

def token_by_address(token_type: str, address: str) -> TokenInfo:
    if token_type == "TON_TOKEN":
        if address == JUSDT_TOKEN_ADDRESS:
            return TokenInfo("jUSDT", 6)
        if address == USDT_TOKEN_ADDRESS:
            return TokenInfo("USDT", 6)
        if address == NOT_TOKEN_ADDRESS:
            return TokenInfo("NOT", 9)

10-10: 🧹 Nitpick (assertive)

Add type hints to function parameters.

Add type hints to improve code clarity and enable better type checking.

-def token_by_address(token_type, address) -> TokenInfo:
+def token_by_address(token_type: str, address: str) -> TokenInfo:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def token_by_address(token_type: str, address: str) -> TokenInfo:
🧰 Tools
🪛 Ruff (0.8.2)

10-10: Missing type annotation for function argument token_type

(ANN001)


10-10: Missing type annotation for function argument address

(ANN001)

core/src/apps/ton/tonsdk/contract/token/nft/nft_utils.py (4)

11-12: 🧹 Nitpick (assertive)

Add type hints to serialize_uri function.

Add type hints to improve code clarity and enable better type checking.

-def serialize_uri(uri):
+def serialize_uri(uri: str) -> bytes:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def serialize_uri(uri: str) -> bytes:
    return urllib.parse.quote(uri, safe="~@#$&()*!+=:;,?/'").encode()
🧰 Tools
🪛 Ruff (0.8.2)

11-11: Missing return type annotation for public function serialize_uri

(ANN201)


11-11: Missing type annotation for function argument uri

(ANN001)


19-23: 🧹 Nitpick (assertive)

Add type hints to create_offchain_uri_cell function.

Add type hints to improve code clarity and enable better type checking.

-def create_offchain_uri_cell(uri):
+def create_offchain_uri_cell(uri: str) -> Cell:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def create_offchain_uri_cell(uri: str) -> Cell:
    cell = Cell()
    cell.bits.write_uint8(OFFCHAIN_CONTENT_PREFIX)
    cell.bits.write_bytes(serialize_uri(uri))
    return cell
🧰 Tools
🪛 Ruff (0.8.2)

19-19: Missing return type annotation for public function create_offchain_uri_cell

(ANN201)


19-19: Missing type annotation for function argument uri

(ANN001)


15-16: 🧹 Nitpick (assertive)

Add type hints to parse_uri function.

Add type hints to improve code clarity and enable better type checking.

-def parse_uri(uri):
+def parse_uri(uri: bytes) -> str:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def parse_uri(uri: bytes) -> str:
    return uri.decode()
🧰 Tools
🪛 Ruff (0.8.2)

15-15: Missing return type annotation for public function parse_uri

(ANN201)


15-15: Missing type annotation for function argument uri

(ANN001)


26-42: 🛠️ Refactor suggestion

Refactor parse_offchain_uri_cell for better validation and remove duplication.

Replace assert with proper validation and remove duplicate length calculation.

-def parse_offchain_uri_cell(cell):
+def parse_offchain_uri_cell(cell: Cell) -> str:
+    if not cell.bits or cell.bits[0] != OFFCHAIN_CONTENT_PREFIX:
+        raise ValueError("Invalid offchain uri cell")
+
     _bytes = b""
-    length = 0
     c = cell
     while c:
-        length += len(c.bits)
-        c = c.refs[0] if c.refs else None
-
-    _bytes = b""
-    length = 0
-    c = cell
-    while c:
         _bytes += c.bits
-        length += len(c.bits)
         c = c.refs[0] if c.refs else None

     return parse_uri(_bytes[1:])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def parse_offchain_uri_cell(cell: Cell) -> str:
    if not cell.bits or cell.bits[0] != OFFCHAIN_CONTENT_PREFIX:
        raise ValueError("Invalid offchain uri cell")

    _bytes = b""
    c = cell
    while c:
        _bytes += c.bits
        c = c.refs[0] if c.refs else None

    return parse_uri(_bytes[1:])
🧰 Tools
🪛 Ruff (0.8.2)

26-26: Missing return type annotation for public function parse_offchain_uri_cell

(ANN201)


26-26: Missing type annotation for function argument cell

(ANN001)


27-27: Use of assert detected

(S101)

core/src/apps/ton/tonsdk/contract/wallet/__init__.py (2)

20-27: 🧹 Nitpick (assertive)

Add ClassVar annotation to mutable class attributes.

Add ClassVar to improve type safety of class attributes.

+from typing import ClassVar, Dict, Type

 class Wallets:
-    default_version = WalletVersionEnum.v3r2
-    ALL = {
+    default_version: ClassVar[WalletVersionEnum] = WalletVersionEnum.v3r2
+    ALL: ClassVar[Dict[WalletVersionEnum, Type[WalletContract]]] = {
         WalletVersionEnum.v3r1: WalletV3ContractR1,
         WalletVersionEnum.v3r2: WalletV3ContractR2,
         WalletVersionEnum.v4r1: WalletV4ContractR1,
         WalletVersionEnum.v4r2: WalletV4ContractR2,
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

from typing import ClassVar, Dict, Type

class Wallets:
    default_version: ClassVar[WalletVersionEnum] = WalletVersionEnum.v3r2
    ALL: ClassVar[Dict[WalletVersionEnum, Type[WalletContract]]] = {
        WalletVersionEnum.v3r1: WalletV3ContractR1,
        WalletVersionEnum.v3r2: WalletV3ContractR2,
        WalletVersionEnum.v4r1: WalletV4ContractR1,
        WalletVersionEnum.v4r2: WalletV4ContractR2,
    }
🧰 Tools
🪛 Ruff (0.8.2)

22-27: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


30-39: 🧹 Nitpick (assertive)

Sort the __all__ list alphabetically.

Sort the list to improve readability and maintainability.

 __all__ = [
+    "SendModeEnum",
+    "WalletContract",
     "WalletV3ContractR1",
     "WalletV3ContractR2",
     "WalletV4ContractR1",
     "WalletV4ContractR2",
-    "WalletContract",
-    "SendModeEnum",
     "WalletVersionEnum",
     "Wallets",
 ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

__all__ = [
    "SendModeEnum",
    "WalletContract",
    "WalletV3ContractR1",
    "WalletV3ContractR2",
    "WalletV4ContractR1",
    "WalletV4ContractR2",
    "WalletVersionEnum",
    "Wallets",
]
🧰 Tools
🪛 Ruff (0.8.2)

30-39: __all__ is not sorted

Apply an isort-style sorting to __all__

(RUF022)

core/src/apps/ton/tonsdk/boc/_dict_builder.py (5)

6-9: 🧹 Nitpick (assertive)

Add type annotations to improve code maintainability.

Add return type annotations and parameter types:

-    def __init__(self, key_size: int):
+    def __init__(self, key_size: int) -> None:
         self.key_size = key_size
         self.items = {}
         self.ended = False
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def __init__(self, key_size: int) -> None:
        self.key_size = key_size
        self.items = {}
        self.ended = False
🧰 Tools
🪛 Ruff (0.8.2)

6-6: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


46-47: 🧹 Nitpick (assertive)

Add type hints to begin_dict function.

-def begin_dict(key_size):
+def begin_dict(key_size: int) -> DictBuilder:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def begin_dict(key_size: int) -> DictBuilder:
    return DictBuilder(key_size)
🧰 Tools
🪛 Ruff (0.8.2)

46-46: Missing return type annotation for private function begin_dict

(ANN202)


46-46: Missing type annotation for function argument key_size

(ANN001)


11-19: 🧹 Nitpick (assertive)

Improve type safety and error handling.

Add type hints and use isinstance for type checks:

-    def store_cell(self, index, value: Cell):
+    def store_cell(self, index: int | bytes, value: Cell) -> 'DictBuilder':
         assert self.ended is False, "Already ended"
-        if type(index) == bytes:
+        if isinstance(index, bytes):
             index = int(index.hex(), 16)

-        assert type(index) == int, "Invalid index type"
+        assert isinstance(index, int), "Invalid index type"
-        assert not (index in self.items), f"Item {index} already exist"
+        assert index not in self.items, f"Item {index} already exists"
         self.items[index] = value
         return self
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def store_cell(self, index: int | bytes, value: Cell) -> 'DictBuilder':
        assert self.ended is False, "Already ended"
        if isinstance(index, bytes):
            index = int(index.hex(), 16)

        assert isinstance(index, int), "Invalid index type"
        assert index not in self.items, f"Item {index} already exists"
        self.items[index] = value
        return self
🧰 Tools
🪛 Ruff (0.8.2)

11-11: Missing return type annotation for private function store_cell

(ANN202)


11-11: Missing type annotation for function argument index

(ANN001)


12-12: Use of assert detected

(S101)


13-13: Use is and is not for type comparisons, or isinstance() for isinstance checks

(E721)


16-16: Use of assert detected

(S101)


16-16: Use is and is not for type comparisons, or isinstance() for isinstance checks

(E721)


17-17: Use of assert detected

(S101)


17-17: Test for membership should be not in

Convert to not in

(E713)


35-38: 🧹 Nitpick (assertive)

Add type hints to default_serializer.

-        def default_serializer(src, dest):
+        def default_serializer(src: Cell, dest: Cell) -> None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        def default_serializer(src: Cell, dest: Cell) -> None:
            dest.write_cell(src)

        return serialize_dict(self.items, self.key_size, default_serializer)
🧰 Tools
🪛 Ruff (0.8.2)

35-35: Missing return type annotation for private function default_serializer

Add return type annotation: None

(ANN202)


35-35: Missing type annotation for function argument src

(ANN001)


35-35: Missing type annotation for function argument dest

(ANN001)


21-27: 🧹 Nitpick (assertive)

Add type hints to store_ref method.

-    def store_ref(self, index, value: Cell):
+    def store_ref(self, index: int | bytes, value: Cell) -> 'DictBuilder':
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def store_ref(self, index: int | bytes, value: Cell) -> 'DictBuilder':
        assert self.ended is False, "Already ended"

        cell = Cell()
        cell.refs.append(value)
        self.store_cell(index, cell)
        return self
🧰 Tools
🪛 Ruff (0.8.2)

21-21: Missing return type annotation for private function store_ref

(ANN202)


21-21: Missing type annotation for function argument index

(ANN001)


22-22: Use of assert detected

(S101)

core/src/apps/ton/tonsdk/contract/token/nft/nft_sale.py (3)

13-25: 🧹 Nitpick (assertive)

Document required options for data cell creation.

Add docstring to explain required options:

     def create_data_cell(self) -> Cell:
+        """Create a data cell for the NFT sale contract.
+        
+        Required options:
+        - marketplace_address: Address of the marketplace
+        - nft_address: Address of the NFT
+        - full_price: Full price in nano-TON
+        - marketplace_fee: Marketplace fee in nano-TON
+        - royalty_address: Address for royalty payments
+        - royalty_amount: Royalty amount in nano-TON
+        
+        Returns:
+            Cell: Data cell for the contract
+        """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def create_data_cell(self) -> Cell:
        """Create a data cell for the NFT sale contract.
        
        Required options:
        - marketplace_address: Address of the marketplace
        - nft_address: Address of the NFT
        - full_price: Full price in nano-TON
        - marketplace_fee: Marketplace fee in nano-TON
        - royalty_address: Address for royalty payments
        - royalty_amount: Royalty amount in nano-TON
        
        Returns:
            Cell: Data cell for the contract
        """
        cell = Cell()
        cell.bits.write_address(self.options["marketplace_address"])
        cell.bits.write_address(self.options["nft_address"])
        cell.bits.write_address(None)  # nft_owner_address
        cell.bits.write_grams(self.options["full_price"])

        fees_cell = Cell()
        fees_cell.bits.write_coins(self.options["marketplace_fee"])
        fees_cell.bits.write_address(self.options["royalty_address"])
        fees_cell.bits.write_coins(self.options["royalty_amount"])
        cell.refs.append(fees_cell)
        return cell

5-6: 🧹 Nitpick (assertive)

Add docstring to explain the NFTSale contract.

Add class documentation:

 class NFTSale(Contract):
+    """NFTSale contract implementation for TON blockchain.
+    
+    This contract handles NFT sale operations including:
+    - Sale creation with marketplace and royalty fees
+    - Sale cancellation
+    """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

class NFTSale(Contract):
    """NFTSale contract implementation for TON blockchain.
    
    This contract handles NFT sale operations including:
    - Sale creation with marketplace and royalty fees
    - Sale cancellation
    """
    code = "B5EE9C7241020A010001B4000114FF00F4A413F4BCF2C80B01020120020302014804050004F2300202CD0607002FA03859DA89A1F481F481F481F401A861A1F401F481F4006101F7D00E8698180B8D8492F82707D201876A2687D207D207D207D006A18116BA4E10159C71D991B1B2990E382C92F837028916382F970FA01698FC1080289C6C8895D7970FAE99F98FD2018201A642802E78B2801E78B00E78B00FD016664F6AA701363804C9B081B2299823878027003698FE99F9810E000C92F857010C0801F5D41081DCD650029285029185F7970E101E87D007D207D0018384008646582A804E78B28B9D090D0A85AD08A500AFD010AE5B564B8FD80384008646582AC678B2803FD010B65B564B8FD80384008646582A802E78B00FD0109E5B564B8FD80381041082FE61E8A10C00C646582A802E78B117D010A65B509E58F8A40900C8C0029A3110471036454012F004E032363704C0038E4782103B9ACA0015BEF2E1C95312C70559C705B1F2E1CA702082105FCC3D14218010C8CB055006CF1622FA0215CB6A14CB1F14CB3F21CF1601CF16CA0021FA02CA00C98100A0FB00E05F06840FF2F0002ACB3F22CF1658CF16CA0021FA02CA00C98100A0FB00AECABAD1"

8-11: 🧹 Nitpick (assertive)

Add type hints to constructor.

-    def __init__(self, **kwargs):
+    def __init__(self, **kwargs: dict[str, Any]) -> None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def __init__(self, **kwargs: dict[str, Any]) -> None:
        self.code = kwargs.get("code") or self.code
        kwargs["code"] = Cell.one_from_boc(self.code)
        super().__init__(**kwargs)
🧰 Tools
🪛 Ruff (0.8.2)

8-8: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


8-8: Missing type annotation for **kwargs

(ANN003)

core/src/apps/ton/tonsdk/boc/_builder.py (5)

82-83: 🧹 Nitpick (assertive)

Add return type annotation to begin_cell.

-def begin_cell():
+def begin_cell() -> Builder:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def begin_cell() -> Builder:
    return Builder()
🧰 Tools
🪛 Ruff (0.8.2)

82-82: Missing return type annotation for private function begin_cell

(ANN202)


76-79: 🧹 Nitpick (assertive)

Add return type annotation to end_cell.

-    def end_cell(self):
+    def end_cell(self) -> Cell:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def end_cell(self) -> Cell:
        cell = Cell()
        cell.write_cell(self)
        return cell
🧰 Tools
🪛 Ruff (0.8.2)

76-76: Missing return type annotation for private function end_cell

(ANN202)


5-10: 🧹 Nitpick (assertive)

Add class documentation and type hints.

 class Builder:
+    """Builder class for constructing TON cells.
+    
+    This class provides methods to build cells by writing various data types
+    into a bit string and managing references to other cells.
+    """
-    def __init__(self):
+    def __init__(self) -> None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

class Builder:
    """Builder class for constructing TON cells.
    
    This class provides methods to build cells by writing various data types
    into a bit string and managing references to other cells.
    """
    def __init__(self) -> None:
        self.bits = BitString(1023)
        self.refs = []
        self.is_exotic = False
🧰 Tools
🪛 Ruff (0.8.2)

6-6: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


11-13: 🧹 Nitpick (assertive)

Add return type annotation to repr.

-    def __repr__(self):
+    def __repr__(self) -> str:
         return f"<Builder refs_num: {len(self.refs)}, {repr(self.bits)}>"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def __repr__(self) -> str:
        return f"<Builder refs_num: {len(self.refs)}, {repr(self.bits)}>"
🧰 Tools
🪛 Ruff (0.8.2)

11-11: Missing return type annotation for special method __repr__

Add return type annotation: str

(ANN204)


12-12: Use explicit conversion flag

Replace with conversion flag

(RUF010)


32-74: 🧹 Nitpick (assertive)

Add type hints to all store methods.

Add comprehensive type hints to improve code maintainability:

-    def store_bit(self, value):
+    def store_bit(self, value: bool) -> 'Builder':

-    def store_bit_array(self, value):
+    def store_bit_array(self, value: list[bool]) -> 'Builder':

-    def store_uint(self, value, bit_length):
+    def store_uint(self, value: int, bit_length: int) -> 'Builder':

-    def store_uint8(self, value):
+    def store_uint8(self, value: int) -> 'Builder':

-    def store_int(self, value, bit_length):
+    def store_int(self, value: int, bit_length: int) -> 'Builder':

-    def store_string(self, value):
+    def store_string(self, value: str) -> 'Builder':

-    def store_bytes(self, value):
+    def store_bytes(self, value: bytes) -> 'Builder':

-    def store_bit_string(self, value):
+    def store_bit_string(self, value: BitString) -> 'Builder':

-    def store_address(self, value):
+    def store_address(self, value: str | None) -> 'Builder':

-    def store_grams(self, value):
+    def store_grams(self, value: int) -> 'Builder':

-    def store_coins(self, value):
+    def store_coins(self, value: int) -> 'Builder':
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def store_bit(self, value: bool) -> 'Builder':
        self.bits.write_bit(value)
        return self

    def store_bit_array(self, value: list[bool]) -> 'Builder':
        self.bits.write_bit_array(value)
        return self

    def store_uint(self, value: int, bit_length: int) -> 'Builder':
        self.bits.write_uint(value, bit_length)
        return self

    def store_uint8(self, value: int) -> 'Builder':
        self.bits.write_uint8(value)
        return self

    def store_int(self, value: int, bit_length: int) -> 'Builder':
        self.bits.write_int(value, bit_length)
        return self

    def store_string(self, value: str) -> 'Builder':
        self.bits.write_string(value)
        return self

    def store_bytes(self, value: bytes) -> 'Builder':
        self.bits.write_bytes(value)
        return self

    def store_bit_string(self, value: BitString) -> 'Builder':
        self.bits.write_bit_string(value)
        return self

    def store_address(self, value: str | None) -> 'Builder':
        self.bits.write_address(value)
        return self

    def store_grams(self, value: int) -> 'Builder':
        self.bits.write_grams(value)
        return self

    def store_coins(self, value: int) -> 'Builder':
        self.bits.write_coins(value)
        return self
🧰 Tools
🪛 Ruff (0.8.2)

32-32: Missing return type annotation for private function store_bit

(ANN202)


32-32: Missing type annotation for function argument value

(ANN001)


36-36: Missing return type annotation for private function store_bit_array

(ANN202)


36-36: Missing type annotation for function argument value

(ANN001)


40-40: Missing return type annotation for private function store_uint

(ANN202)


40-40: Missing type annotation for function argument value

(ANN001)


40-40: Missing type annotation for function argument bit_length

(ANN001)


44-44: Missing return type annotation for private function store_uint8

(ANN202)


44-44: Missing type annotation for function argument value

(ANN001)


48-48: Missing return type annotation for private function store_int

(ANN202)


48-48: Missing type annotation for function argument value

(ANN001)


48-48: Missing type annotation for function argument bit_length

(ANN001)


52-52: Missing return type annotation for private function store_string

(ANN202)


52-52: Missing type annotation for function argument value

(ANN001)


56-56: Missing return type annotation for private function store_bytes

(ANN202)


56-56: Missing type annotation for function argument value

(ANN001)


60-60: Missing return type annotation for private function store_bit_string

(ANN202)


60-60: Missing type annotation for function argument value

(ANN001)


64-64: Missing return type annotation for private function store_address

(ANN202)


64-64: Missing type annotation for function argument value

(ANN001)


68-68: Missing return type annotation for private function store_grams

(ANN202)


68-68: Missing type annotation for function argument value

(ANN001)


72-72: Missing return type annotation for private function store_coins

(ANN202)


72-72: Missing type annotation for function argument value

(ANN001)

core/src/apps/ton/layout.py (4)

61-74: 🧹 Nitpick (assertive)

Remove or implement commented code.

The function works correctly, but contains commented code that should be addressed.

Either remove the commented code or implement the feature for handling small decimal numbers.


45-58: 🧹 Nitpick (assertive)

Move hardcoded string to constants.

The function works well but has a hardcoded string.

Extract "Ton" to a constant:

+TON_CURRENCY_NAME = "Ton"

 def require_show_overview(
     ctx: Context,
     to_addr: str,
     value: int,
     token: tokens.TokenInfo | None = None,
 ) -> Awaitable[bool]:
     return should_show_details(
         ctx,
-        title=_(i18n_keys.TITLE__STR_TRANSACTION).format("Ton"),
+        title=_(i18n_keys.TITLE__STR_TRANSACTION).format(TON_CURRENCY_NAME),
         address=to_addr,
         amount=format_ton_amount(value, token),
         br_code=ButtonRequestType.SignTx,
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

TON_CURRENCY_NAME = "Ton"

def require_show_overview(
    ctx: Context,
    to_addr: str,
    value: int,
    token: tokens.TokenInfo | None = None,
) -> Awaitable[bool]:

    return should_show_details(
        ctx,
        title=_(i18n_keys.TITLE__STR_TRANSACTION).format(TON_CURRENCY_NAME),
        address=to_addr,
        amount=format_ton_amount(value, token),
        br_code=ButtonRequestType.SignTx,
    )

77-87: 🧹 Nitpick (assertive)

Move icon path to constants.

The function works well but has a hardcoded icon path.

Extract the icon path to a constant:

+UNKNOWN_TOKEN_ICON = "A:/res/shriek.png"

 def require_confirm_unknown_token(ctx: Context, address: str) -> Awaitable[None]:
     return confirm_address(
         ctx,
         _(i18n_keys.TITLE__UNKNOWN_TOKEN),
         address,
         description=_(i18n_keys.LIST_KEY__CONTRACT__COLON),
         br_type="unknown_token",
-        icon="A:/res/shriek.png",
+        icon=UNKNOWN_TOKEN_ICON,
         icon_color=ui.ORANGE,
         br_code=ButtonRequestType.SignTx,
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

UNKNOWN_TOKEN_ICON = "A:/res/shriek.png"

def require_confirm_unknown_token(ctx: Context, address: str) -> Awaitable[None]:
    return confirm_address(
        ctx,
        _(i18n_keys.TITLE__UNKNOWN_TOKEN),
        address,
        description=_(i18n_keys.LIST_KEY__CONTRACT__COLON),
        br_type="unknown_token",
        icon=UNKNOWN_TOKEN_ICON,
        icon_color=ui.ORANGE,
        br_code=ButtonRequestType.SignTx,
    )

17-42: 🧹 Nitpick (assertive)

Add docstring to explain parameters and return value.

The function logic looks good. It correctly handles fee calculations and formatting.

Add a docstring like this:

 def require_confirm_fee(
     ctx: Context,
     from_address: str | None = None,
     to_address: str | None = None,
     value: int = 0,
     gas_price: int = 0,
     gas_limit: int = 0,
     token: tokens.TokenInfo | None = None,
     raw_data: bytes | None = None,
     is_raw_data: bool = False,
 ) -> Awaitable[None]:
+    """
+    Prompt user to confirm transaction fee.
+    
+    Args:
+        ctx: Wire context
+        from_address: Sender address
+        to_address: Recipient address
+        value: Transaction value
+        gas_price: Gas price
+        gas_limit: Gas limit
+        token: Token info if token transfer
+        raw_data: Raw transaction data
+        is_raw_data: Whether raw_data is present
+    """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def require_confirm_fee(
    ctx: Context,
    from_address: str | None = None,
    to_address: str | None = None,
    value: int = 0,
    gas_price: int = 0,
    gas_limit: int = 0,
    token: tokens.TokenInfo | None = None,
    raw_data: bytes | None = None,
    is_raw_data: bool = False,
) -> Awaitable[None]:
    """
    Prompt user to confirm transaction fee.
    
    Args:
        ctx: Wire context
        from_address: Sender address
        to_address: Recipient address
        value: Transaction value
        gas_price: Gas price
        gas_limit: Gas limit
        token: Token info if token transfer
        raw_data: Raw transaction data
        is_raw_data: Whether raw_data is present
    """
    from trezor.ui.layouts.lvgl.altcoin import confirm_total_ton

    fee_limit = gas_price * gas_limit

    return confirm_total_ton(
        ctx,
        format_ton_amount(value, token),
        None,
        format_ton_amount(fee_limit, None),
        from_address,
        to_address,
        format_ton_amount(value + fee_limit, None) if token is None else None,
        raw_data=raw_data,
        is_raw_data=is_raw_data,
    )
🧰 Tools
🪛 Ruff (0.8.2)

26-26: Boolean-typed positional argument in function definition

(FBT001)


26-26: Boolean default positional argument in function definition

(FBT002)

core/src/apps/ton/tonsdk/contract/token/nft/nft_item.py (3)

45-49: 🛠️ Refactor suggestion

Add validation for query_id in get_static_data_body.

Similar to create_transfer_body, this method should validate query_id.

Add validation:

 def create_get_static_data_body(self, query_id: int = 0) -> Cell:
+    if not 0 <= query_id < 2**64:
+        raise ValueError("query_id must be a 64-bit unsigned integer")
     cell = Cell()
     cell.bits.write_uint(0x2FCB26A2, 32)
     cell.bits.write_uint(query_id, 64)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def create_get_static_data_body(self, query_id: int = 0) -> Cell:
        if not 0 <= query_id < 2**64:
            raise ValueError("query_id must be a 64-bit unsigned integer")
        cell = Cell()
        cell.bits.write_uint(0x2FCB26A2, 32)
        cell.bits.write_uint(query_id, 64)
        return cell

6-7: 🧹 Nitpick (assertive)

Document the code string's purpose.

Add a docstring explaining what the hex code represents.

 class NFTItem(Contract):
     code = "B5EE9C7241020D010001D0000114FF00F4A413F4BCF2C80B0102016202030202CE04050009A11F9FE00502012006070201200B0C02D70C8871C02497C0F83434C0C05C6C2497C0F83E903E900C7E800C5C75C87E800C7E800C3C00812CE3850C1B088D148CB1C17CB865407E90350C0408FC00F801B4C7F4CFE08417F30F45148C2EA3A1CC840DD78C9004F80C0D0D0D4D60840BF2C9A884AEB8C097C12103FCBC20080900113E910C1C2EBCB8536001F65135C705F2E191FA4021F001FA40D20031FA00820AFAF0801BA121945315A0A1DE22D70B01C300209206A19136E220C2FFF2E192218E3E821005138D91C85009CF16500BCF16712449145446A0708010C8CB055007CF165005FA0215CB6A12CB1FCB3F226EB39458CF17019132E201C901FB00104794102A375BE20A00727082108B77173505C8CBFF5004CF1610248040708010C8CB055007CF165005FA0215CB6A12CB1FCB3F226EB39458CF17019132E201C901FB000082028E3526F0018210D53276DB103744006D71708010C8CB055007CF165005FA0215CB6A12CB1FCB3F226EB39458CF17019132E201C901FB0093303234E25502F003003B3B513434CFFE900835D27080269FC07E90350C04090408F80C1C165B5B60001D00F232CFD633C58073C5B3327B5520BF75041B"
+    """NFT Item smart contract code in hex format.
+    
+    This code implements the NFT Item standard interface for TON blockchain.
+    """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

class NFTItem(Contract):
    code = "B5EE9C7241020D010001D0000114FF00F4A413F4BCF2C80B0102016202030202CE04050009A11F9FE00502012006070201200B0C02D70C8871C02497C0F83434C0C05C6C2497C0F83E903E900C7E800C5C75C87E800C7E800C3C00812CE3850C1B088D148CB1C17CB865407E90350C0408FC00F801B4C7F4CFE08417F30F45148C2EA3A1CC840DD78C9004F80C0D0D0D4D60840BF2C9A884AEB8C097C12103FCBC20080900113E910C1C2EBCB8536001F65135C705F2E191FA4021F001FA40D20031FA00820AFAF0801BA121945315A0A1DE22D70B01C300209206A19136E220C2FFF2E192218E3E821005138D91C85009CF16500BCF16712449145446A0708010C8CB055007CF165005FA0215CB6A12CB1FCB3F226EB39458CF17019132E201C901FB00104794102A375BE20A00727082108B77173505C8CBFF5004CF1610248040708010C8CB055007CF165005FA0215CB6A12CB1FCB3F226EB39458CF17019132E201C901FB000082028E3526F0018210D53276DB103744006D71708010C8CB055007CF165005FA0215CB6A12CB1FCB3F226EB39458CF17019132E201C901FB0093303234E25502F003003B3B513434CFFE900835D27080269FC07E90350C04090408F80C1C165B5B60001D00F232CFD633C58073C5B3327B5520BF75041B"
    """NFT Item smart contract code in hex format.

    This code implements the NFT Item standard interface for TON blockchain.
    """

9-13: 🧹 Nitpick (assertive)

Add type hints to constructor.

The constructor needs proper type hints.

-    def __init__(self, **kwargs):
+    def __init__(self, **kwargs: dict[str, Any]) -> None:

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

9-9: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


9-9: Missing type annotation for **kwargs

(ANN003)

core/src/apps/ton/tonsdk/contract/token/ft/jetton_wallet.py (3)

38-46: 🛠️ Refactor suggestion

Add validation for jetton_amount.

The burn operation should validate the amount.

     def create_burn_body(
         self, jetton_amount: int, response_address: Address = None, query_id: int = 0
     ) -> Cell:
+        if jetton_amount <= 0:
+            raise ValueError("Burn amount must be positive")
         cell = Cell()
         cell.bits.write_uint(0x595F07BC, 32)  # burn OP
         cell.bits.write_uint(query_id, 64)
         cell.bits.write_grams(jetton_amount)
         cell.bits.write_address(response_address)
         return cell
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def create_burn_body(
        self, jetton_amount: int, response_address: Address = None, query_id: int = 0
    ) -> Cell:
        if jetton_amount <= 0:
            raise ValueError("Burn amount must be positive")
        cell = Cell()
        cell.bits.write_uint(0x595F07BC, 32)  # burn OP
        cell.bits.write_uint(query_id, 64)
        cell.bits.write_grams(jetton_amount)
        cell.bits.write_address(response_address)
        return cell
🧰 Tools
🪛 Ruff (0.8.2)

39-39: Trailing comma missing

Add trailing comma

(COM812)


24-36: 🧹 Nitpick (assertive)

Move operation codes to constants.

Extract magic numbers to named constants.

+    # Operation codes
+    REQUEST_TRANSFER_OP = 0xF8A7EA5
+
     def create_transfer_body(
         self,
         to_address: Address,
         jetton_amount: int,
         forward_amount: int = 0,
         forward_payload: str = None,
         response_address: Address = None,
         query_id: int = 0,
     ) -> Cell:
         cell = Cell()
-        cell.bits.write_uint(0xF8A7EA5, 32)  # request_transfer op
+        cell.bits.write_uint(self.REQUEST_TRANSFER_OP, 32)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

# Operation codes
REQUEST_TRANSFER_OP = 0xF8A7EA5

def create_transfer_body(
    self,
    to_address: Address,
    jetton_amount: int,
    forward_amount: int = 0,
    forward_payload: str = None,
    response_address: Address = None,
    query_id: int = 0,
) -> Cell:
    cell = Cell()
    cell.bits.write_uint(self.REQUEST_TRANSFER_OP, 32)  # request_transfer op
    cell.bits.write_uint(query_id, 64)
    cell.bits.write_grams(jetton_amount)
    cell.bits.write_address(to_address)
    cell.bits.write_address(response_address or to_address)
    cell.bits.write_bit(0)  # null custom_payload
    cell.bits.write_grams(forward_amount)
    cell.bits.write_bit(0)  # forward_payload in this slice, not separate cell
    if forward_payload:
        cell.bits.write_uint(0, 32)
        cell.bits.write_string(forward_payload)

    return cell

6-7: 🧹 Nitpick (assertive)

Document the code string's purpose.

Add a docstring explaining what the hex code represents.

 class JettonWallet(Contract):
     code = "B5EE9C7241021201000328000114FF00F4A413F4BCF2C80B0102016202030202CC0405001BA0F605DA89A1F401F481F481A8610201D40607020148080900BB0831C02497C138007434C0C05C6C2544D7C0FC02F83E903E900C7E800C5C75C87E800C7E800C00B4C7E08403E29FA954882EA54C4D167C0238208405E3514654882EA58C511100FC02780D60841657C1EF2EA4D67C02B817C12103FCBC2000113E910C1C2EBCB853600201200A0B020120101101F500F4CFFE803E90087C007B51343E803E903E90350C144DA8548AB1C17CB8B04A30BFFCB8B0950D109C150804D50500F214013E809633C58073C5B33248B232C044BD003D0032C032483E401C1D3232C0B281F2FFF274013E903D010C7E801DE0063232C1540233C59C3E8085F2DAC4F3208405E351467232C7C6600C03F73B51343E803E903E90350C0234CFFE80145468017E903E9014D6F1C1551CDB5C150804D50500F214013E809633C58073C5B33248B232C044BD003D0032C0327E401C1D3232C0B281F2FFF274140371C1472C7CB8B0C2BE80146A2860822625A020822625A004AD822860822625A028062849F8C3C975C2C070C008E00D0E0F009ACB3F5007FA0222CF165006CF1625FA025003CF16C95005CC2391729171E25008A813A08208989680AA008208989680A0A014BCF2E2C504C98040FB001023C85004FA0258CF1601CF16CCC9ED5400705279A018A182107362D09CC8CB1F5230CB3F58FA025007CF165007CF16C9718018C8CB0524CF165006FA0215CB6A14CCC971FB0010241023000E10491038375F040076C200B08E218210D53276DB708010C8CB055008CF165004FA0216CB6A12CB1F12CB3FC972FB0093356C21E203C85004FA0258CF1601CF16CCC9ED5400DB3B51343E803E903E90350C01F4CFFE803E900C145468549271C17CB8B049F0BFFCB8B0A0822625A02A8005A805AF3CB8B0E0841EF765F7B232C7C572CFD400FE8088B3C58073C5B25C60063232C14933C59C3E80B2DAB33260103EC01004F214013E809633C58073C5B3327B55200083200835C87B51343E803E903E90350C0134C7E08405E3514654882EA0841EF765F784EE84AC7CB8B174CFCC7E800C04E81408F214013E809633C58073C5B3327B55205ECCF23D"
+    """Jetton Wallet smart contract code in hex format.
+    
+    This code implements the Jetton Wallet standard interface for TON blockchain.
+    """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

class JettonWallet(Contract):
    code = "B5EE9C7241021201000328000114FF00F4A413F4BCF2C80B0102016202030202CC0405001BA0F605DA89A1F401F481F481A8610201D40607020148080900BB0831C02497C138007434C0C05C6C2544D7C0FC02F83E903E900C7E800C5C75C87E800C7E800C00B4C7E08403E29FA954882EA54C4D167C0238208405E3514654882EA58C511100FC02780D60841657C1EF2EA4D67C02B817C12103FCBC2000113E910C1C2EBCB853600201200A0B020120101101F500F4CFFE803E90087C007B51343E803E903E90350C144DA8548AB1C17CB8B04A30BFFCB8B0950D109C150804D50500F214013E809633C58073C5B33248B232C044BD003D0032C032483E401C1D3232C0B281F2FFF274013E903D010C7E801DE0063232C1540233C59C3E8085F2DAC4F3208405E351467232C7C6600C03F73B51343E803E903E90350C0234CFFE80145468017E903E9014D6F1C1551CDB5C150804D50500F214013E809633C58073C5B33248B232C044BD003D0032C0327E401C1D3232C0B281F2FFF274140371C1472C7CB8B0C2BE80146A2860822625A020822625A004AD822860822625A028062849F8C3C975C2C070C008E00D0E0F009ACB3F5007FA0222CF165006CF1625FA025003CF16C95005CC2391729171E25008A813A08208989680AA008208989680A0A014BCF2E2C504C98040FB001023C85004FA0258CF1601CF16CCC9ED5400705279A018A182107362D09CC8CB1F5230CB3F58FA025007CF165007CF16C9718018C8CB0524CF165006FA0215CB6A14CCC971FB0010241023000E10491038375F040076C200B08E218210D53276DB708010C8CB055008CF165004FA0216CB6A12CB1F12CB3FC972FB0093356C21E203C85004FA0258CF1601CF16CCC9ED5400DB3B51343E803E903E90350C01F4CFFE803E900C145468549271C17CB8B049F0BFFCB8B0A0822625A02A8005A805AF3CB8B0E0841EF765F7B232C7C572CFD400FE8088B3C58073C5B25C60063232C14933C59C3E80B2DAB33260103EC01004F214013E809633C58073C5B3327B55200083200835C87B51343E803E903E90350C0134C7E08405E3514654882EA0841EF765F784EE84AC7CB8B174CFCC7E800C04E81408F214013E809633C58073C5B3327B55205ECCF23D"
    """Jetton Wallet smart contract code in hex format.
    
    This code implements the Jetton Wallet standard interface for TON blockchain.
    """
core/src/trezor/strings.py (2)

96-98: 🧹 Nitpick (assertive)

Enhance the docstring.

The docstring should explain the function's behavior for different inputs and the hex fallback.

     """
-    Returns human-friendly representation of a customer data.
+    Returns human-friendly representation of customer data.
+
+    Args:
+        data: Customer data as bytes or None
+
+    Returns:
+        - Empty string if data is None or empty
+        - Decoded string if data contains printable characters
+        - Hex string prefixed with "0x" if data contains non-printable characters
     """
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    """
    Returns human-friendly representation of customer data.

    Args:
        data: Customer data as bytes or None

    Returns:
        - Empty string if data is None or empty
        - Decoded string if data contains printable characters
        - Hex string prefixed with "0x" if data contains non-printable characters
    """

103-104: 🧹 Nitpick (assertive)

Document the magic number and non-printable character check.

The check for non-printable characters in the first 33 bytes needs explanation. Add a comment explaining why 33 bytes and why non-printable characters matter.

+        # Check first 33 bytes for non-printable characters
+        # (33 bytes is the standard TON address length)
         if all((c <= 0x20 or c == 0x7F) for c in data[:33]):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        # Check first 33 bytes for non-printable characters
        # (33 bytes is the standard TON address length)
        if all((c <= 0x20 or c == 0x7F) for c in data[:33]):
            raise UnicodeError  # non-printable characters
🧰 Tools
🪛 Ruff (0.8.2)

104-104: Abstract raise to an inner function

(TRY301)

core/src/apps/ton/tonsdk/utils/_utils.py (3)

43-58: 🧹 Nitpick (assertive)

Optimize CRC32C calculation.

The repeated code for bit operations can be simplified using a lookup table.

Consider using a pre-computed lookup table to improve performance and readability. I can help generate an optimized implementation if needed.

🧰 Tools
🪛 Ruff (0.8.2)

43-43: Missing return type annotation for private function _crc32c

(ANN202)


43-43: Missing type annotation for function argument crc

(ANN001)


43-43: Missing type annotation for function argument bytes_arr

(ANN001)


99-100: ⚠️ Potential issue

Fix the string comparison of bytes.

Using string comparison for bytes is inefficient and potentially unsafe.

 def compare_bytes(bytes_1, bytes_2):
-    return str(bytes_1) == str(bytes_2)  # why str?
+    return bytes_1 == bytes_2
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def compare_bytes(bytes_1, bytes_2):
    return bytes_1 == bytes_2
🧰 Tools
🪛 Ruff (0.8.2)

99-99: Missing return type annotation for private function compare_bytes

(ANN202)


99-99: Missing type annotation for function argument bytes_1

(ANN001)


99-99: Missing type annotation for function argument bytes_2

(ANN001)


103-116: 🛠️ Refactor suggestion

Simplify string to bytes conversion.

The function has several issues:

  1. Commented-out code
  2. Unclear size parameter usage
  3. Direct assignment of character to buffer
 def string_to_bytes(string, size=1):
-    if size == 1:
-        buf = bytearray(len(string))
-    elif size == 2:
-        buf = bytearray(len(string) * 2)
-    elif size == 4:
-        buf = bytearray(len(string) * 4)
-    else:
-        raise Exception("Invalid size")
-
-    for i, c in enumerate(string):
-        # buf[i] = ord(c)
-        buf[i] = c  # ?
-
-    return bytes(buf)
+    if size not in (1, 2, 4):
+        raise ValueError("Size must be 1, 2, or 4")
+    return string.encode()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def string_to_bytes(string, size=1):
    if size not in (1, 2, 4):
        raise ValueError("Size must be 1, 2, or 4")
    return string.encode()
🧰 Tools
🪛 Ruff (0.8.2)

103-103: Missing return type annotation for private function string_to_bytes

(ANN202)


103-103: Missing type annotation for function argument string

(ANN001)


103-103: Missing type annotation for function argument size

(ANN001)


111-111: Create your own exception

(TRY002)


111-111: Avoid specifying long messages outside the exception class

(TRY003)

core/src/apps/ton/tonsdk/contract/wallet/_wallet_contract_v4.py (1)

8-12: ⚠️ Potential issue

Add validation for wallet_id and public_key.

The data cell creation lacks input validation for critical fields.

     def create_data_cell(self):
         cell = Cell()
+        if "wallet_id" not in self.options:
+            raise ValueError("wallet_id is required")
+        if "public_key" not in self.options:
+            raise ValueError("public_key is required")
         cell.bits.write_uint(0, 32)
         cell.bits.write_uint(self.options["wallet_id"], 32)
         cell.bits.write_bytes(self.options["public_key"])
         cell.bits.write_uint(0, 1)  # plugins dict empty
         return cell
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def create_data_cell(self):
        cell = Cell()
        if "wallet_id" not in self.options:
            raise ValueError("wallet_id is required")
        if "public_key" not in self.options:
            raise ValueError("public_key is required")
        cell.bits.write_uint(0, 32)
        cell.bits.write_uint(self.options["wallet_id"], 32)
        cell.bits.write_bytes(self.options["public_key"])
        cell.bits.write_uint(0, 1)  # plugins dict empty
        return cell
core/src/trezor/ui/layouts/lvgl/altcoin.py (2)

181-194: 🛠️ Refactor suggestion

Add type conversion for token_id.

The token_id conversion to string should handle None case.

     screen = TransactionDetailsTON(
         _(i18n_keys.TITLE__TRANSACTION_DETAILS),
         from_address,
         to_address,
         amount,
         fee_max,
         gas_price=gas_price,
         total_amount=total_amount,
         primary_color=ctx.primary_color,
         contract_addr=contract_addr,
-        token_id=str(token_id),
+        token_id=str(token_id) if token_id is not None else None,
         evm_chain_id=evm_chain_id,
         raw_data=raw_data,
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    screen = TransactionDetailsTON(
        _(i18n_keys.TITLE__TRANSACTION_DETAILS),
        from_address,
        to_address,
        amount,
        fee_max,
        gas_price=gas_price,
        total_amount=total_amount,
        primary_color=ctx.primary_color,
        contract_addr=contract_addr,
        token_id=str(token_id) if token_id is not None else None,
        evm_chain_id=evm_chain_id,
        raw_data=raw_data,
    )

165-178: ⚠️ Potential issue

Remove unused parameter and add validation.

The is_raw_data parameter is unused, and some parameters lack validation.

 async def confirm_total_ton(
     ctx: wire.GenericContext,
     amount: str,
     gas_price: str | None,
     fee_max: str,
     from_address: str | None,
     to_address: str | None,
     total_amount: str | None,
     contract_addr: str | None = None,
     token_id: int | None = None,
     evm_chain_id: int | None = None,
     raw_data: bytes | None = None,
-    is_raw_data: bool = False,
 ) -> None:
+    if not amount:
+        raise ValueError("Amount is required")
+    if not fee_max:
+        raise ValueError("Fee max is required")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

async def confirm_total_ton(
    ctx: wire.GenericContext,
    amount: str,
    gas_price: str | None,
    fee_max: str,
    from_address: str | None,
    to_address: str | None,
    total_amount: str | None,
    contract_addr: str | None = None,
    token_id: int | None = None,
    evm_chain_id: int | None = None,
    raw_data: bytes | None = None,
) -> None:
    if not amount:
        raise ValueError("Amount is required")
    if not fee_max:
        raise ValueError("Fee max is required")
    # ... continue with the rest of the function logic
🧰 Tools
🪛 Ruff (0.8.2)

177-177: Boolean-typed positional argument in function definition

(FBT001)


177-177: Boolean default positional argument in function definition

(FBT002)


177-177: Unused function argument: is_raw_data

(ARG001)

core/src/apps/ton/tonsdk/boc/_bit_string.py (4)

54-56: 🛠️ Refactor suggestion

Create custom exceptions for better error handling.

Replace generic exceptions with custom ones for better error handling and clarity.

Add these custom exceptions at the beginning of the file:

class BitStringOverflowError(Exception):
    """Raised when bit operations exceed the allocated length."""
    pass

class BitStringValueError(Exception):
    """Raised when invalid bit values are provided."""
    pass

class BitStringFormatError(Exception):
    """Raised when input format is incorrect."""
    pass

Then update the exception raising:

-            raise Exception("BitString overflow")
+            raise BitStringOverflowError(f"Operation exceeds allocated length of {self.length} bits")

Also applies to: 76-77, 112-113, 121-123, 147-148

🧰 Tools
🪛 Ruff (0.8.2)

55-55: Create your own exception

(TRY002)


55-55: Avoid specifying long messages outside the exception class

(TRY003)


183-183: 🧹 Nitpick (assertive)

Replace ambiguous variable name.

The variable name 'l' is ambiguous. Use a more descriptive name like 'length' or 'byte_length'.

-            l = math.ceil(len(hex(amount)[2:]) / 2)  # ? [2:] removes 0x
+            byte_length = math.ceil(len(hex(amount)[2:]) / 2)  # [2:] removes 0x prefix
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

            byte_length = math.ceil(len(hex(amount)[2:]) / 2)  # [2:] removes 0x prefix
🧰 Tools
🪛 Ruff (0.8.2)

183-183: Ambiguous variable name: l

(E741)


100-104: 🧹 Nitpick (assertive)

Optimize string decoding in write_bit_array.

The current implementation decodes the entire bytearray at once. Consider processing bytes directly.

-    def write_bit_array(self, ba: bytearray | bytes):
-        """Writes a bytearray as a bit array one bit by one."""
-        for b in ba.decode("utf-8"):
+    def write_bit_array(self, ba: bytearray | bytes) -> None:
+        """Writes a bytearray as a bit array one bit by one."""
+        for b in ba:
             self.write_bit(b)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    def write_bit_array(self, ba: bytearray | bytes) -> None:
        """Writes a bytearray as a bit array one bit by one."""
        for b in ba:
            self.write_bit(b)
🧰 Tools
🪛 Ruff (0.8.2)

100-100: Missing return type annotation for private function write_bit_array

Add return type annotation: None

(ANN202)


6-11: 🧹 Nitpick (assertive)

Add return type hints to special methods.

Add return type annotations to __init__, __repr__, __iter__, __getitem__, and __len__ methods.

-    def __init__(self, length: int):
+    def __init__(self, length: int) -> None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

class BitString:
    def __init__(self, length: int) -> None:
        self.array = bytearray(math.ceil(length / 8))
        self.cursor = 0
        self.length = length
🧰 Tools
🪛 Ruff (0.8.2)

7-7: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)

python/src/trezorlib/cli/ton.py (3)

33-38: 🧹 Nitpick (assertive)

Clean up commented wallet versions.

Either remove or implement the commented wallet versions. Dead code can confuse maintainers.

WALLET_VERSION = {
-    # "v3r1": messages.TonWalletVersion.V3R1,
-    # "v3r2": messages.TonWalletVersion.V3R2,
-    # "v4r1": messages.TonWalletVersion.V4R1,
    "v4r2": messages.TonWalletVersion.V4R2,
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

WALLET_VERSION = {
    "v4r2": messages.TonWalletVersion.V4R2,
}

48-48: 🧹 Nitpick (assertive)

Document the hardcoded wallet ID.

Add a comment explaining the significance of the default wallet ID value (698983191).

-    @click.option("-i", "--wallet-id", type=int, default=698983191)
+    @click.option("-i", "--wallet-id", type=int, default=698983191,
+                  help="Wallet ID for TON operations (default: mainnet v4r2 wallet)")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

@click.option("-i", "--wallet-id", type=int, default=698983191,
              help="Wallet ID for TON operations (default: mainnet v4r2 wallet)")

119-120: 🧹 Nitpick (assertive)

Uncomment or remove commented code.

The commented expiration time calculation should either be removed or implemented.

-    # expire_at = int(time.time()) + 300
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    resp = ton.sign_message(
core/src/trezor/ui/layouts/lvgl/__init__.py (1)

1905-1919: 🧹 Nitpick (assertive)

Add return type annotation and improve error handling.

The function needs a return type annotation and should handle potential errors from confirm_address.

-def confirm_unknown_token_transfer(
+def confirm_unknown_token_transfer(
     ctx: wire.GenericContext,
     address: str,
-):
+) -> Awaitable[None]:
     return confirm_address(
         ctx,
         _(i18n_keys.TITLE__UNKNOWN_TOKEN),
         address,
         description=_(i18n_keys.LIST_KEY__CONTRACT_ADDRESS__COLON),
         br_type="unknown_token",
         icon="A:/res/warning.png",
         icon_color=ui.ORANGE,
         br_code=ButtonRequestType.SignTx,
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

def confirm_unknown_token_transfer(
    ctx: wire.GenericContext,
    address: str,
) -> Awaitable[None]:
    return confirm_address(
        ctx,
        _(i18n_keys.TITLE__UNKNOWN_TOKEN),
        address,
        description=_(i18n_keys.LIST_KEY__CONTRACT_ADDRESS__COLON),
        br_type="unknown_token",
        icon="A:/res/warning.png",
        icon_color=ui.ORANGE,
        br_code=ButtonRequestType.SignTx,
    )
🧰 Tools
🪛 Ruff (0.8.2)

1905-1905: Missing return type annotation for public function confirm_unknown_token_transfer

(ANN201)

core/src/trezor/lvglui/scrs/template.py (1)

853-921: 🧹 Nitpick (assertive)

Add type hints and improve code organization.

The TonMessage class needs type hints and better code organization:

  1. Add return type annotations
  2. Add type hints for parameters
  3. Remove commented-out code
 class TonMessage(FullSizeWindow):
     def __init__(
         self,
-        title,
-        address,
-        message,
-        domain,
-        primary_color,
-        icon_path,
-        verify: bool = False,
+        title: str,
+        address: str,
+        message: str,
+        domain: str,
+        primary_color: int,
+        icon_path: str,
+        verify: bool = False,
     ) -> None:
         # ... rest of the code ...

-    def eventhandler(self, event_obj):
+    def eventhandler(self, event_obj) -> None:
         # ... rest of the code ...

-            # self.show_full_message = NormalButton(
-            #     self, _(i18n_keys.BUTTON__VIEW_FULL_MESSAGE)
-            # )
-            # self.show_full_message.align_to(self.item2, lv.ALIGN.OUT_BOTTOM_MID, 0, 32)
-            # self.show_full_message.add_event_cb(self.on_click, lv.EVENT.CLICKED, None)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

class TonMessage(FullSizeWindow):
    def __init__(
        self,
        title: str,
        address: str,
        message: str,
        domain: str,
        primary_color: int,
        icon_path: str,
        verify: bool = False,
    ) -> None:
        super().__init__(
            title,
            None,
            _(i18n_keys.BUTTON__VERIFY) if verify else _(i18n_keys.BUTTON__SIGN),
            _(i18n_keys.BUTTON__CANCEL),
            anim_dir=2,
            primary_color=primary_color,
            icon_path=icon_path,
        )
        self.primary_color = primary_color
        self.container = ContainerFlexCol(
            self.content_area, self.title, pos=(0, 40), padding_row=8
        )
        if domain:
            self.item3 = DisplayItemNoBgc(
                self.container,
                _(i18n_keys.LIST_KEY__DOMAIN__COLON),
                str(domain),
            )
        self.item1 = DisplayItemNoBgc(
            self.container, _(i18n_keys.LIST_KEY__ADDRESS__COLON), address
        )
        self.long_message = False
        if len(message) > 80:
            self.message = message
            self.long_message = True
            self.btn_yes.label.set_text(_(i18n_keys.BUTTON__VIEW))
        else:
            self.item2 = DisplayItemNoBgc(
                self.container, _(i18n_keys.LIST_KEY__MESSAGE__COLON), message
            )

    def eventhandler(self, event_obj) -> None:
        code = event_obj.code
        target = event_obj.get_target()
        if code == lv.EVENT.CLICKED:
            if target == self.btn_yes:
                if self.long_message:
                    PageAbleMessage(
                        _(i18n_keys.LIST_KEY__MESSAGE__COLON),
                        self.message,
                        self.channel,
                        primary_color=self.primary_color,
                        confirm_text=_(i18n_keys.BUTTON__SIGN),
                    )
                    self.destroy()
                else:
                    self.show_unload_anim()
                    self.channel.publish(1)
            elif target == self.btn_no:
                self.show_dismiss_anim()
                self.channel.publish(0)
🧰 Tools
🪛 Ruff (0.8.2)

854-854: Missing return type annotation for special method __init__

Add return type annotation: None

(ANN204)


856-856: Missing type annotation for function argument title

(ANN001)


857-857: Missing type annotation for function argument address

(ANN001)


858-858: Missing type annotation for function argument message

(ANN001)


859-859: Missing type annotation for function argument domain

(ANN001)


860-860: Missing type annotation for function argument primary_color

(ANN001)


861-861: Missing type annotation for function argument icon_path

(ANN001)


862-862: Boolean-typed positional argument in function definition

(FBT001)


862-862: Boolean default positional argument in function definition

(FBT002)


875-875: Trailing comma missing

Add trailing comma

(COM812)


884-884: Trailing comma missing

Add trailing comma

(COM812)


898-898: Trailing comma missing

Add trailing comma

(COM812)


901-901: Missing return type annotation for public function eventhandler

Add return type annotation: None

(ANN201)


901-901: Missing type annotation for function argument event_obj

(ANN001)

core/src/trezor/messages.py (2)

65-66: 🧹 Nitpick (assertive)

Remove unnecessary noqa directives.

The noqa: F401 directives are not needed for these imports as they are used in the code.

-    from trezor.enums import TonWalletVersion  # noqa: F401
-    from trezor.enums import TonWorkChain  # noqa: F401
+    from trezor.enums import TonWalletVersion
+    from trezor.enums import TonWorkChain
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    from trezor.enums import TonWalletVersion
    from trezor.enums import TonWorkChain
🧰 Tools
🪛 Ruff (0.8.2)

65-65: Unused noqa directive (unused: F401)

Remove unused noqa directive

(RUF100)


66-66: Unused noqa directive (unused: F401)

Remove unused noqa directive

(RUF100)


8364-8378: ⚠️ Potential issue

Fix typo in field name.

The field "signning_message" has a typo - it should be "signing_message".

-        signning_message: "bytes | None"
+        signing_message: "bytes | None"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    class TonSignedMessage(protobuf.MessageType):
        signature: "bytes | None"
        signing_message: "bytes | None"

        def __init__(
            self,
            *,
            signature: "bytes | None" = None,
            signning_message: "bytes | None" = None,
        ) -> None:
            pass

        @classmethod
        def is_type_of(cls, msg: Any) -> TypeGuard["TonSignedMessage"]:
            return isinstance(msg, cls)
🧰 Tools
🪛 Ruff (0.8.2)

8377-8377: Dynamically typed expressions (typing.Any) are disallowed in msg

(ANN401)

python/src/trezorlib/messages.py (1)

10309-10384: 🧹 Nitpick (assertive)

Consider adding field documentation.

The TonSignMessage has many fields but lacks documentation explaining their purpose. Add comments to describe key fields like jetton_amount, fwd_fee, and mode.

🧰 Tools
🪛 Ruff (0.8.2)

10311-10334: Mutable class attributes should be annotated with typing.ClassVar

(RUF012)


10362-10362: Remove quotes from type annotation

Remove quotes

(UP037)


10363-10363: Remove quotes from type annotation

Remove quotes

(UP037)


10364-10364: Remove quotes from type annotation

Remove quotes

(UP037)


10365-10365: Remove quotes from type annotation

Remove quotes

(UP037)

core/src/apps/ton/tonsdk/contract/token/nft/__init__.py (1)

5-9: 🧹 Nitpick (assertive)

Sort the all List.
Sorting the __all__ list alphabetically improves clarity and consistency.

-__all__ = [
-    "NFTItem",
-    "NFTCollection",
-    "NFTSale",
-]
+__all__ = [
+    "NFTCollection",
+    "NFTItem",
+    "NFTSale",
+]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

__all__ = [
    "NFTCollection",
    "NFTItem",
    "NFTSale",
]
🧰 Tools
🪛 Ruff (0.8.2)

5-9: __all__ is not sorted

Apply an isort-style sorting to __all__

(RUF022)

common/protob/messages-ton.proto (5)

1-3: ⚠️ Potential issue

Package Directory Mismatch.
The declared package is hw.trezor.messages.ton, but this file is located in common/protob. Please either move the file to hw/trezor/messages/ton or update its package declaration for consistency.

🧰 Tools
🪛 Buf (1.47.2)

2-2: Files with package "hw.trezor.messages.ton" must be within a directory "hw/trezor/messages/ton" relative to root but were in directory "common/protob".

(PACKAGE_DIRECTORY_MATCH)


39-42: 🛠️ Refactor suggestion

Revisit Field Requirements in TonAddress.
Using required fields can hinder forward compatibility. Evaluate whether public_key and address should be marked as optional instead.

🧰 Tools
🪛 Buf (1.47.2)

40-40: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


41-41: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


50-63: 🛠️ Refactor suggestion

Reconsider 'required' Usage in TonSignMessage.
Several fields (e.g., destination, ton_amount, seqno, expire_at) are marked as required. Switching these to optional could enable smoother evolution of your message schema.

🧰 Tools
🪛 Buf (1.47.2)

52-52: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


55-55: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


61-61: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


62-62: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


90-97: 🛠️ Refactor suggestion

Review 'required' Fields in TonSignProof.
The fields appdomain and expire_at are declared as required. Consider changing them to optional to enhance compatibility and future-proof your protocol.

🧰 Tools
🪛 Buf (1.47.2)

92-92: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


94-94: Field named %!q(MISSING) should not be required.

(FIELD_NOT_REQUIRED)


8-13: ⚠️ Potential issue

Enum Value Starting at Non-Zero.
Protocol buffer best practices recommend that the first enum value be 0. Consider revising the enum so that the first active value starts at 0—or ensure that using V4R2 = 3 is an intentional design decision. For example:

-    V4R2 = 3;
+    V4R2 = 0;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

enum TonWalletVersion {
    // V3R1 = 0;
    // V3R2 = 1;
    // V4R1 = 2;
    V4R2 = 0;
}
🧰 Tools
🪛 Buf (1.47.2)

12-12: First enum value "V4R2" should have a numeric value of 0

(ENUM_FIRST_VALUE_ZERO)

common/protob/messages.proto (1)

523-529: 🛠️ Refactor suggestion

Enum Naming Convention for New TON Messages

The newly added TON message types do not follow the UPPER_SNAKE_CASE standard required for enum values. For consistency, please rename them. For instance, change MessageType_TonGetAddress to MESSAGE_TYPE_TON_GET_ADDRESS and update the others accordingly.

-    MessageType_TonGetAddress = 11901 [(wire_in) = true];
-    MessageType_TonAddress = 11902 [(wire_out) = true];
-    MessageType_TonSignMessage = 11903 [(wire_in) = true];
-    MessageType_TonSignedMessage = 11904 [(wire_out) = true];
-    MessageType_TonSignProof = 11905 [(wire_in) = true];
-    MessageType_TonSignedProof = 11906 [(wire_out) = true];
+    MESSAGE_TYPE_TON_GET_ADDRESS = 11901 [(wire_in) = true];
+    MESSAGE_TYPE_TON_ADDRESS = 11902 [(wire_out) = true];
+    MESSAGE_TYPE_TON_SIGN_MESSAGE = 11903 [(wire_in) = true];
+    MESSAGE_TYPE_TON_SIGNED_MESSAGE = 11904 [(wire_out) = true];
+    MESSAGE_TYPE_TON_SIGN_PROOF = 11905 [(wire_in) = true];
+    MESSAGE_TYPE_TON_SIGNED_PROOF = 11906 [(wire_out) = true];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

    // Ton
    MESSAGE_TYPE_TON_GET_ADDRESS = 11901 [(wire_in) = true];
    MESSAGE_TYPE_TON_ADDRESS = 11902 [(wire_out) = true];
    MESSAGE_TYPE_TON_SIGN_MESSAGE = 11903 [(wire_in) = true];
    MESSAGE_TYPE_TON_SIGNED_MESSAGE = 11904 [(wire_out) = true];
    MESSAGE_TYPE_TON_SIGN_PROOF = 11905 [(wire_in) = true];
    MESSAGE_TYPE_TON_SIGNED_PROOF = 11906 [(wire_out) = true];
🧰 Tools
🪛 Buf (1.47.2)

524-524: Enum value name "MessageType_TonGetAddress" should be UPPER_SNAKE_CASE, such as "MESSAGE_TYPE_TON_GET_ADDRESS".

(ENUM_VALUE_UPPER_SNAKE_CASE)


525-525: Enum value name "MessageType_TonAddress" should be UPPER_SNAKE_CASE, such as "MESSAGE_TYPE_TON_ADDRESS".

(ENUM_VALUE_UPPER_SNAKE_CASE)


526-526: Enum value name "MessageType_TonSignMessage" should be UPPER_SNAKE_CASE, such as "MESSAGE_TYPE_TON_SIGN_MESSAGE".

(ENUM_VALUE_UPPER_SNAKE_CASE)


527-527: Enum value name "MessageType_TonSignedMessage" should be UPPER_SNAKE_CASE, such as "MESSAGE_TYPE_TON_SIGNED_MESSAGE".

(ENUM_VALUE_UPPER_SNAKE_CASE)


528-528: Enum value name "MessageType_TonSignProof" should be UPPER_SNAKE_CASE, such as "MESSAGE_TYPE_TON_SIGN_PROOF".

(ENUM_VALUE_UPPER_SNAKE_CASE)


529-529: Enum value name "MessageType_TonSignedProof" should be UPPER_SNAKE_CASE, such as "MESSAGE_TYPE_TON_SIGNED_PROOF".

(ENUM_VALUE_UPPER_SNAKE_CASE)

Signed-off-by: Lu1zz <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12a120e and b15dcc3.

📒 Files selected for processing (1)
  • core/src/apps/ton/sign_message.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
core/src/apps/ton/sign_message.py

23-23: sign_message is too complex (11 > 10)

(C901)


24-24: Trailing comma missing

Add trailing comma

(COM812)


37-37: Avoid specifying long messages outside the exception class

(TRY003)


42-42: Trailing comma missing

Add trailing comma

(COM812)


56-56: Boolean positional value in function call

(FBT003)


56-56: Boolean positional value in function call

(FBT003)


64-64: Avoid specifying long messages outside the exception class

(TRY003)


69-69: Avoid specifying long messages outside the exception class

(TRY003)


92-92: Trailing comma missing

Add trailing comma

(COM812)


149-149: Unnecessary elif after return statement

Remove unnecessary elif

(RET505)


155-155: Avoid specifying long messages outside the exception class

(TRY003)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Style check
  • GitHub Check: Defs check
  • GitHub Check: Gen check

@Lu1zz Lu1zz merged commit 9598a49 into OneKeyHQ:touch Feb 21, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants